﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharePointSearchBench.Library
{
    /// <summary>
    /// Represents a condition used in a SharePoint CAML query Where clause.
    /// </summary>
    public class CamlCondition
    {
        string conditionText;
        const string BaseFieldRef = "<FieldRef Name=\"{0}\"/>";
        const string BaseValue = "<Value Type=\"{0}\">{1}</Value>";
        CamlCondition peer;
        LogicalOperator logicalOperator;

        private CamlCondition(string conditionText)
        {
            this.conditionText = conditionText;
        }

        public static CamlCondition Equality(string fieldName, string fieldType, string value)
        {
            string fieldRef = string.Format(CamlCondition.BaseFieldRef, fieldName);
            string valueText = string.Format(CamlCondition.BaseValue, fieldType, value);
            return CamlCondition.BaseEquality(fieldRef, valueText);
        }

        public static CamlCondition Equality(string fieldName, string value)
        {
            string fieldRef = string.Format(CamlCondition.BaseFieldRef, fieldName);
            string valueText = string.Format(CamlCondition.BaseValue, "Text", value);
            return CamlCondition.BaseEquality(fieldRef, valueText);
        }

        public static CamlCondition Equality(string fieldName, int value)
        {
            string fieldRef = string.Format(CamlCondition.BaseFieldRef, fieldName);
            string valueText = string.Format(CamlCondition.BaseValue, "Integer", value.ToString());
            return CamlCondition.BaseEquality(fieldRef, valueText);
        }

        static CamlCondition BaseEquality(string fieldRefElement, string valueElement)
        {
            string condition = "<Eq>{0}{1}</Eq>";
            return new CamlCondition(string.Format(condition, fieldRefElement, valueElement));
        }

        public void And(CamlCondition peer)
        {
            this.logicalOperator = LogicalOperator.And;
            this.peer = peer;
        }

        public void Or(CamlCondition peer)
        {
            this.logicalOperator = LogicalOperator.Or;
            this.peer = peer;
        }

        public override string ToString()
        {
            if(this.peer == null)
            {
                return this.GetConditionValue();
            }
            else
            {
                string oper = "And";

                if(this.logicalOperator == LogicalOperator.Or)
                {
                    oper = "Or";
                }

                string text = "<{0}>{1}{2}</{0}>";
                string thisCondition = this.GetConditionValue();
                return string.Format(text, oper, thisCondition, this.peer.ToString());
            }
        }

        string GetConditionValue()
        {
            return string.Format("{0}", this.conditionText);
        }

    }
}
